# -*- coding: utf-8 -*-
__author__ = 'vladbranzei'

from cherrypy import HTTPError
from configs import configs as conf

class Permission(object):

    credentials = game = allowed = disallowed = None

    def __init__(self, i_credentials, i_game, i_allowed, i_disallowed):
        self.credentials = i_credentials
        self.game = i_game
        self.allowed = i_allowed
        self.disallowed = i_disallowed


class PermissionMapper(object):
    def __init__(self):
        self.foundPermissions = None
        self.client = conf.client

    def check(self, vid, game):
        query = {}
        query['vid'] = vid
        query['game'] = game

        try:
            user_permission = self.client.freya.permissions.find(query)
            count = user_permission.count()
            if count == 1:
                self.foundPermissions = user_permission[0]
                return True
            else:
                return False
        except Exception as e:
            raise HTTPError(503)

    def create(self, vid, game, allowed_permissions=None, disallowed_permissions=None):
        try:
            if allowed_permissions:
                allowed = list(allowed_permissions)
            else:
                allowed = []

            if disallowed_permissions:
                disallowed = list(disallowed_permissions)
            else:
                disallowed = []

            result = self.client.freya.permissions.insert({'vid': vid, 'game': game,'allowed':allowed,'disallowed':disallowed})
            return result
        except Exception as e:
            #log this error
            raise HTTPError(503)

    def add_permission(self, i_vid, i_game, i_permissions):
        try:
            if self.check(i_vid, i_game):
                existing_permissions = self.foundPermissions["allowed"]
                remaining_permissions = list(i_permissions)

                for wpermission in i_permissions:
                    for epermission in existing_permissions:
                        if wpermission == epermission:
                            try:
                                remaining_permissions.remove(wpermission)
                            except ValueError as e:
                                pass

                if not remaining_permissions:
                    return "Credential already has these permissions"

                result = self.client.freya.permissions.update({"vid": i_vid}, {"$push": {"allowed": {"$each": remaining_permissions}}})
                if result['ok']:
                    return True
                else:
                    return False
            else:
                if self.create(i_vid, i_game, i_permissions):
                    return True
                else:
                    return False
        except HTTPError as e:
            raise HTTPError(e.code)
        except Exception as e:
            raise HTTPError(503)

    def remove_permission(self, i_vid, i_game, i_permissions):
        try:
            if self.check(i_vid, i_game):
                existing_permissions = self.foundPermissions["disallowed"]
                remaining_permissions = list(i_permissions)

                for wpermission in i_permissions:
                    for epermission in existing_permissions:
                        if wpermission == epermission:
                            try:
                                remaining_permissions.remove(wpermission)
                            except ValueError as e:
                                pass

                if not remaining_permissions:
                    return "Credential already has these permissions removed"

                result = self.client.freya.permissions.update({"vid": i_vid}, {"$push":{"disallowed": {"$each": remaining_permissions}}})

                if result['ok']:
                    return True
                else:
                    return False
            else:
                if self.create(i_vid, i_game, None, []):
                    return True
                else:
                    return False
        except HTTPError as e:
            raise e
        except Exception as e:
            raise e
